﻿#region changelog
/*
 * 02/04/09 - wbw (Seagull Consulting): Original code
 * 02/13/09 - wbw : Change file extension on TvDBXMLFile from mpg.xml to xml.  append xml to the OutputFile in the Profile to construct the file name.
 * 02/13/09 - wbw : Add Obfuscation functionality for the APIKey
 * 02/20/09 - wbw : Add FileDialog functionality for TemplateXMLFile and SeriesAliasFile
 * 11/22/11 - as : Refactored API key storage to remove dependency on babgvant GAC assembly
*/
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Durrant.Common;
using Durrant.Plugins.TvDB;

namespace Durrant.Plugins
{
    [Serializable()]
    public class TvDBMetaData : BaseAction
    {
        private string templateSageXMLFileName = "Template.mpg.xml";
        [PluginConfigure("TemplateXMLFile", ConfigType.FileDialog, "XML|*.xml|All Files|*.*")]
        public string TemplateXMLFileName
        {
            get { return templateSageXMLFileName; }
            set { templateSageXMLFileName = value; }
        }

        private string seriesAliasFileName = "SeriesAlias.xml";
        [PluginConfigure("SeriesAliasFile", ConfigType.FileDialog, "XML|*.xml|All Files|*.*")]
        public string SeriesAliasFileName
        {
            get { return seriesAliasFileName; }
            set { seriesAliasFileName = value; }
        }

        private string targetContext = "TvDBXMLFile";
        [PluginConfigure(ConfigType.Context)]
        public string TargetContext
        {
            get { return targetContext; }
            set { targetContext = value; }
        }

        //use a regex to decode filename, create one profile per file naming convention
        private string sourceRegEx = string.Empty;
        [PluginConfigure("Extraction Regex", ConfigType.Empty)]
        public string SourceRegEx
        {
            get { return sourceRegEx; }
            set { sourceRegEx = value; } 
        }

        protected override string GetDescription()
        {
            return "Read metadata from TvDB and build Sage XML file.";
        }

        public override void  Process()
        {
            Match m;
            Series series;
            Episode episode;
            SageXMLFile sageFile;
            string seriesXML, episodeXML = string.Empty;
            string outFullFileName = string.Empty;
            string templateXMLFileName = string.Empty;
            string extractionRegex = string.Empty;

            try
            {
                lows.Info("Processing TvDBMetaData with " + Context.Count.ToString() + " arguments.");
                if (Context.Count > 0)
                {

                    //Validate a Template XML Filename was passed to me
                    //if (Context.ContainsKey(TemplateXMLFile))
                    if (TemplateXMLFileName.Length > 0)
                        lows.Info("Using following file as Template Metadata XML file: " + TemplateXMLFileName);
                    else
                        throw new Exception("Template Metadata XML filename not passed as argument.");

                    //Validate a Series XML Filename was passed to me
                    if (seriesAliasFileName.Length > 0)
                        lows.Info("Using following file as Series Alias XML file: " + SeriesAliasFileName);
                    else
                        throw new Exception("Series Alias filename not passed as argument.");

                    //Validate a target Sage XML Filename was passed to me
                    if (TargetContext != null)
                    {
                        outFullFileName = (string) Context[TargetContext];
                        lows.Info("Using following file as the target Metadata XML file: " + outFullFileName);
                    }
                    else
                        throw new Exception("Target Metadata XML filename not passed as argument.");

                        if (SourceRegEx.Length > 0)
                    {
                        extractionRegex = SourceRegEx;
                        lows.Info("Using input parameter as regular expression: " + extractionRegex);
                    }
                    else
                    {
                        extractionRegex = Constants.EXTRACTION_REGEX;
                        lows.Info("Using default regular expression: " + extractionRegex);
                    }
                }
                else
                    throw new Exception("No parameters passed to process.");


                //Retrieve TheTvDB API Key
                lows.Info(string.Format("Metadata provided by thetvdb.com ({0})", GetType().Assembly));

                // TODO: implement encryption to secure the api key
                TVDB.APIKey = CryptographyHelper.Decrypt(Constants.API_KEY, Constants.ENCRYPTION_PASSWORD);

                if (TVDB.APIKey.Length > 0)
                    lows.Info("Found APIKey.");
                else
                    throw new Exception("Unable to retrieve APIKey.");

                TVDB.TemplateXMLFileName = TemplateXMLFileName;
                TVDB.SeriesAliasFileName = SeriesAliasFileName;
                //lows.Info("Calling TVDB.init()");
                TVDB.init();
                    //lows.Info("API Key: " + TVDB.APIKey);
                    //lows.Info("Template XML FileName: " + TVDB.TemplateXMLFileName);
                    //lows.Info("Series XML FileName: " + TVDB.SeriesAliasFileName);

                series = new Series();
                episode = new Episode();

                m = Regex.Match(Path.GetFileName(outFullFileName), extractionRegex);

                //Parse Filename and store results
                series.fileName = m.Groups["series"].Value;
                episode.Season = m.Groups["season"].Value;
                episode.Nbr = m.Groups["episodenbr"].Value;

                //lows.Info("Series fileName: " + series.fileName);
                //lows.Info("Episode Season: " + episode.Season);
                //lows.Info("Episode Nbr: " + episode.Nbr);

                //Retrieve Series info and display
                if (TVDB.setSeriesId(series.getURLName()))
                {
                    lows.Info("Found Series Name");
                    seriesXML = TVDB.getSeriesXMLById();
                    if (seriesXML.Length != 0)
                    {
                        lows.Info("Retreived Series Info");
                        series.Id = TVDB.SeriesId;
                        series.parse(seriesXML);

                        //Retrieve Episode info and display
                        episodeXML = TVDB.getEpisodeXML(episode.Season, episode.Nbr);
                        if (episodeXML.Length != 0)
                        {
                            lows.Info("Retreived Episode Info");
                            episode.parse(episodeXML);

                            sageFile = new SageXMLFile();

                            //expects file name will equal full path + filename
                            if (sageFile.create(outFullFileName, series, episode))
                            {
                                lows.Info("Sage XML file created: " + outFullFileName);
                                this.Success = true;
                            }
                            else
                            {
                                lows.Info("Error creating Sage XML file: " + outFullFileName + " with error message: " + sageFile.errorMessage);
                                this.Success = false;
                            }
                        }
                        else
                        {
                            lows.Info("Unable to find Episode in TvDB Database.");
                            this.Success = false;
                        }
                    }
                    else
                    {
                        lows.Info("Unable to find Series in TvDB Database.");
                        this.Success = false;
                    }
                }
            }
            catch (Exception ex)
            {
                lows.Info("Error: {0}", ex.Message);
                this.Success = false;
            }
        }

    } //end of class
} //end of namespace
